﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Diagnostics;
using System.Reflection;
using Sinacor.Infra.UI.Resources;
using System.Runtime.InteropServices;
using Sinacor.UI.HelpViewer.Service;
using PSE.Framework.Configuration;
using PSE.Framework.UI.Resources;

namespace Sinacor.Infra.UI.HelpViewer.Client
{
    public class HelpViewerClient
    {
        #region Attributes

        //Restore the window (not maximized nor minimized). 
        private const int SW_RESTORE = 9;
        private const string URI = "net.pipe://localhost/HelpViewer";
        private const string DefaultPipeName = "Pipe";

        #endregion

        #region Methods

        #region Win32

        [DllImport("user32")]
        public static extern int ShowWindow(int hwnd, int nCmdShow);

        [DllImport("user32")]
        public static extern int UpdateWindow(int hwnd);

        #endregion

        public void ChangeLanguage(string language)
        {
            if (IsSinacorHelpStarted())
            {
                try
                {
                    IPipeService proxy = CreateEndPoint();
                    proxy.ChangeLanguage(language);
                }
                catch (Exception ex)
                {
                    throw new Exception((string)ResourceProviderManager.GetResourceProvider().TryGetResource("Infra.UI.Message.ClientHelpViewer"), ex);
                }
            }
        }

        public void ChangeTheme(string theme)
        {
            if (IsSinacorHelpStarted())
            {
                try
                {
                    IPipeService proxy = CreateEndPoint();
                    proxy.ChangeTheme(theme);
                }
                catch (Exception ex)
                {
                    throw new Exception((string)ResourceProviderManager.GetResourceProvider().TryGetResource("Infra.UI.Message.ClientHelpViewer"), ex);
                }
            }
        }

        public void ShowHelp()
        {
            StartSinacorHelp();
        }

        public void ShowHelp(string document)
        {
            IPipeService proxy = null;

            StartSinacorHelp();

            for (int i = 1; i <= 20; i++)
            {
                try
                {
                    proxy = CreateEndPoint();
                    proxy.ShowHelp(document);
                    break;
                }
                catch (Exception ex)
                {
                    if (i == 20)
                        throw new Exception((string)ResourceProviderManager.GetResourceProvider().TryGetResource("Infra.UI.Message.ClientHelpViewer"), ex);
                    else
                        System.Threading.Thread.Sleep(3000);
                }
            }
        }

        private bool IsSinacorHelpStarted()
        {
            return Process.GetProcessesByName("SinacorHelp").Length > 0;
        }

        private static void StartSinacorHelp()
        {
            Process[] process = Process.GetProcessesByName("SinacorHelp");
            Process p = null;

            if (process.Length == 0)
            {
                string applicationHelpLocation = System.IO.Path.Combine(ApplicationConfiguration.GetApplicationRootDirectory(), System.Configuration.ConfigurationSettings.AppSettings["ApplicationHelpLocation"]);

                p = new Process();
                p.StartInfo.FileName = applicationHelpLocation;
                p.Start();
            }
            else
            {
                int i = int.Parse(process[0].MainWindowHandle.ToString());
                if (i != 0)
                {
                    ShowWindow(i, SW_RESTORE);
                    UpdateWindow(i);
                }
            }
        }
      
        private IPipeService CreateEndPoint()
        {
            EndpointAddress ep = new EndpointAddress(string.Format("{0}/{1}", URI, DefaultPipeName));
            IPipeService proxy = ChannelFactory<IPipeService>.CreateChannel(new NetNamedPipeBinding(), ep);
            return proxy;
        }

        #endregion
    }   
}
